package com.dw.widget.slideshow.utils;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileFilter;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FilenameFilter;
import java.io.IOException;
import java.util.List;

import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.graphics.BitmapFactory;

import com.dw.widget.slideshow.objects.Size;

public class ImageUtils {

	/**
	 * 获取图片分辨率
	 * @param path
	 * @return
	 */
	public static Size getResolution(String path)
	{
		BitmapFactory.Options options = new BitmapFactory.Options();
		options.inJustDecodeBounds = true;
		
		try
		{
			BitmapFactory.decodeFile(path, options);
			
			Size size = new Size(options.outWidth, options.outHeight);
			return size;
		}
		catch(Exception ex)
		{
			ex.printStackTrace();
		}
		
		return null;
	}
	
	/**
	 * 缩小图片
	 * @param path
	 * @param size
	 * @return
	 */
	public static Bitmap ZoomOut(String path, Size size)
	{
		Size originalSize = getResolution(path);
		if(originalSize == null)
		{
			return null;
		}
		
		int destWidth = size.getWidth();
		int destHeight = size.getHeight();
		
		int originalWidth = originalSize.getWidth();
		int originalHeight = originalSize.getHeight();
		
		int sample;
		if(destWidth > originalWidth || destHeight > originalHeight)    // 不需要缩小
		{
			sample = 1;
		}
		else if(destWidth / originalWidth <= destHeight / originalHeight)
		{
			sample = (int)(originalHeight / destHeight);
		}
		else
		{
			sample = (int)(originalWidth / destWidth);
		}
		
		try
		{
			BitmapFactory.Options options = new BitmapFactory.Options();
			options.inSampleSize = sample;
			Bitmap bmp = BitmapFactory.decodeFile(path, options);
			return bmp;
		}
		catch(Exception ex)
		{
			ex.printStackTrace();
		}
		
		return null;
	}
	
	/**
	 * 分割图片为目标尺寸
	 * @param image  源文件
	 * @param ratio   宽 / 高
	 */
	public static Bitmap[] splitImage(Bitmap image, float ratio)
	{
		if(image == null)
		{
			return null;
		}
		
		int width = image.getWidth();
		int height = image.getHeight();
		
		int splitCountH = 1, splitCountV = 1;     // 分割的片段数，横向和纵向
		int startX = 0, startY = 0;    // 分割起始位置
		
		Bitmap[] bmps;
		
		float imageRatio = (float)width / (float)height;
		if(imageRatio <= ratio )     // 图片比较长
		{
			splitCountV = (int)(ratio / imageRatio);
			
			int h = (int)(width / ratio);
			int th = (int)(splitCountV * h);
			startY = (height - th) / 2;
			
			bmps = new Bitmap[splitCountV];
			for(int i = 0; i < splitCountV; i++)
			{
				int x = startX;
				int y = startY + i * h;
				bmps[i] = Bitmap.createBitmap(image, x, y, width, h);
			}
		}
		else
		{
			splitCountH = (int)(imageRatio / ratio);
			
			int w = (int)(height * ratio);
			int tw = (int)(splitCountH * w);
			startX = (width - tw) / 2;
			
			bmps = new Bitmap[splitCountH];
			for(int i = 0; i < splitCountH; i++)
			{
				int x = startX + i * w;
				int y = startY;
				bmps[i] = Bitmap.createBitmap(image, x, y, w, height);
			}
		}
		
		return bmps;
	}
	
	/**
	 * 图片序列化为文件
	 * byte[0] - 子图片数
	 * byte[1]～byte[2] 第一张图片的字节数m
	 * byte[3]~byte[m+2] 第一张图片数据
	 * ...
	 */
	public static void Serialize2File(Bitmap[] images, String file)
	{
		int length = images.length;
		if(images == null ||  length<= 0)
		{
			return;
		}
		
		// 创建路径
		String strClipDir = file.substring(0, file.lastIndexOf("/"));
		File clipDir = new File(strClipDir);
		if(clipDir.exists() == false)
		{
			clipDir.mkdirs();
		}
		
		// 目标文件如果已存在则删除
		File outputFile = new File(file);
		if(outputFile.exists())
		{
			outputFile.delete();
		}
		
		FileOutputStream fos = null;
		try {
			if(outputFile.createNewFile() == false)
			{
				return;
			}
			
			fos = new FileOutputStream(outputFile);
			fos.write((byte)length);
			for(int i = 0; i < length; i++)
			{
				Bitmap bmp = images[i];
				byte[] bytes = getBytes(bmp, CompressFormat.JPEG);
				
				int bCount = bytes.length;
				fos.write((byte)(bCount & 0xff));    // 低位
				fos.write((byte)(bCount >> 8));    // 高位
				fos.write((byte)(bCount >> 16)); 
				fos.write((byte)(bCount >> 24));
				
				// 图片数据
				fos.write(bytes);
			}
			
		} catch (Exception e) {
			e.printStackTrace();
		}
		finally{
			if(fos != null)
			{
				try {
					fos.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}
	
	/**
	 * Serialize2File函数的反向操作
	 * @param file
	 * @return
	 */
	public static Bitmap[] DeserializeFromFile(String file)
	{
		if(file == null || "".equals(file))
		{
			return null;
		}
		
		File inputFile = new File(file);
		if(inputFile.exists() == false)
		{
			return null;
		}
		
		FileInputStream fis = null;
		try {
			fis = new FileInputStream(inputFile);
			int length = fis.read();
			if(length <= 0)
			{
				return null;
			}
			
			Bitmap[] images = new Bitmap[length];
			for(int i = 0; i < length; i++)
			{
				int b1 = fis.read();
				int b2 = fis.read();
				int b3 = fis.read();
				int b4 = fis.read();
				int count = ((b4 << 24) & 0xff000000) + ((b3 << 16) & 0xff0000) + ((b2 << 8) & 0xff00) + (b1 & 0xff);
				
				byte[] buffer = new byte[count];
				fis.read(buffer, 0, count);
				Bitmap bmp = getBitmap(buffer);
				images[i] = bmp;
			}
			
			return images;
		} catch (Exception e) {
			e.printStackTrace();
		}
		finally{
			if(fis != null)
			{
				try {
					fis.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
		
		return null;
	}
	
	public static Bitmap getBitmap(byte[] data) {
		return BitmapFactory.decodeByteArray(data, 0, data.length);
	}

	public static byte[] getBytes(Bitmap bitmap, CompressFormat format) {
		ByteArrayOutputStream baops = new ByteArrayOutputStream();
		bitmap.compress(format, 100, baops);
		return baops.toByteArray();
	}
	
	public static void saveBitmap(Bitmap bmp, String path)
	{
		if(bmp == null || path == null)
		{
			return;
		}
		
		FileOutputStream fos = null;
		try {
			fos = new FileOutputStream(path);
			if(bmp.compress(Bitmap.CompressFormat.JPEG, 100, fos))
			{
				fos.flush();
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		finally{
			if(fos != null)
			{
				try {
					fos.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}
	
	/**
	 * 判断是否为图片文件
	 * @param path
	 * @return
	 */
	public static boolean isImageFile(String path)
	{
		if(path == null || path == "")
		{
			return false;
		}
		
		if(path.endsWith(".jpg") || path.endsWith(".png"))
		{
			return true;
		}
		
		return false;
	}
	
	/**
	 * 递归列出目录下所有的图片文件
	 * @param path
	 * @return
	 */
	public static void listImageFiles(String path, List<File> images)
	{
		
		if(path == null || "".equals(path))
		{
			return;
		}
		
		File file = new File(path);
		
		File[] subFolders = file.listFiles(new FileFilter() {
			
			@Override
			public boolean accept(File pathname) {
				
				// 非隐藏文件夹
				if(pathname.isDirectory() == true && pathname.getName().startsWith(".") == false)
				{
					return true;
				}
				
				return false;
			}
		});
		
		if(subFolders != null && subFolders.length > 0)
		{
			for(File subFolder : subFolders)
			{
				listImageFiles(subFolder.getAbsolutePath(), images);
			}
		}
		
		File[] imagePaths = file.listFiles(new FilenameFilter() {
			
			@Override
			public boolean accept(File dir, String filename) {
				
				if(isImageFile(filename))
				{
					return true;
				}
				
				return false;
			}
		});
		
		if(imagePaths != null)
		{
			for(File image : imagePaths)
			{
				images.add(image);
			}
		}
	}
}
